package utils

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"time"
)

type goFastDfsResp struct {
	Domain  string `json:"domain"`
	Md5     string `json:"md5"`
	MTime   int64  `json:"mtime"`
	Path    string `json:"path"`
	Retcode int64  `json:"retcode"`
	Retmsg  string `json:"retmsg"`
	Scene   string `json:"scene"`
	Scenes  string `json:"scenes"`
	Size    int64  `json:"size"`
	Src     string `json:"src"`
	Url     string `json:"url"`
}

func newFastDfsResp() *goFastDfsResp {
	return &goFastDfsResp{}
}

// 通过md5值查询文件服务器是否存在, 并获取文件信息
func (goFastDfsResp) GoFastDfsGetInfoByMd5(md5 string, goFastDns string) (*goFastDfsResp, error) {
	fmt.Println("开始查询md5文件")
	// url := "http://42.194.198.29:8080/group1/upload"
	ctx, cannFunc := context.WithTimeout(context.Background(), 10*time.Second)
	defer cannFunc()
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, goFastDns, nil)
	if err != nil {
		return nil, err
	}
	query := httpReq.URL.Query()
	query.Add("md5", md5)
	query.Add("output", "json")
	httpReq.URL.RawQuery = query.Encode()
	httpRes, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, err
	}
	defer httpRes.Body.Close()
	resBody, err := io.ReadAll(httpRes.Body)
	if err != nil {
		return nil, err
	}
	resp := new(goFastDfsResp)
	err = json.Unmarshal(resBody, resp)
	if err != nil {
		return nil, err
	}
	fmt.Println("查md5文件成功")
	return resp, nil
}

// 上传文件到文件服务器
func (goFastDfsResp) GoFastDfsClient(fileByte []byte, fileName string, fileSize int64, goFastDns string) (*goFastDfsResp, error) {
	// url := "http://42.194.198.29:8080/group1/upload"
	bodyBuf := bytes.NewBufferString("")
	bodyWrite := multipart.NewWriter(bodyBuf)
	_, err := bodyWrite.CreateFormFile("file", fileName)
	if err != nil {
		return nil, err
	}

	boundary := bodyWrite.Boundary()
	close_buf := bytes.NewBufferString(fmt.Sprintf("\r\n--%s--\r\n", boundary))
	file := bytes.NewReader(fileByte)
	request_render := io.MultiReader(bodyBuf, file, close_buf)

	ctx, cannFunc := context.WithTimeout(context.Background(), 10*time.Second)
	defer cannFunc()
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, goFastDns, request_render)
	if err != nil {
		return nil, err
	}
	query := httpReq.URL.Query()
	query.Add("output", "json")
	query.Add("scene", "")
	query.Add("path", "")
	httpReq.URL.RawQuery = query.Encode()
	httpReq.Header.Add("Content-Type", "multipart/form-data; boundary="+boundary)
	httpReq.ContentLength = fileSize + int64(bodyBuf.Len()) + int64(close_buf.Len())
	httpRes, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, err
	}
	defer httpRes.Body.Close()
	resBody, err := io.ReadAll(httpRes.Body)
	if err != nil {
		return nil, err
	}
	resp := new(goFastDfsResp)
	err = json.Unmarshal(resBody, resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
